package com.zhiche.wms.admin.aop;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.Arrays;

/**
 * @Author: caiHua
 * @Description:
 * @Date: Create in 14:35 2019/2/28
 */
@Aspect     // 表示一个切面bean
@Component  // bean容器的组件注解。虽然放在contrller包里，但它不是控制器。如果注入service,但我们又没有放在service包里
@Order(3)   // 有多个日志时，ORDER可以定义切面的执行顺序（数字越大，前置越后执行，后置越前执行）
public class AspetAop {
    private static final Logger LOGGER = LoggerFactory.getLogger(AspetAop.class);

    private static ThreadLocal<Long> startTime = new ThreadLocal<Long>();


    /**
     * 定义切入点
     * 1、execution 表达式主体
     * 2、第1个* 表示返回值类型  *表示所有类型
     * 3、包名  com.*.*.controller下
     * 4、第4个* 类名，com.*.*.controller包下所有类
     * 5、第5个* 方法名，com.*.*.controller包下所有类所有方法
     * 6、(..) 表示方法参数，..表示任何参数
     */
    @Pointcut("execution(public * com.zhiche.wms.admin.controller..*.*(..))")
    public void wmsWebAopLog () {

    }

    /**
     * 方法里面注入连接点
     *
     * @param joinPoint
     */
    @Before("wmsWebAopLog()")
    public void dobefore (JoinPoint joinPoint) {
        //info ,debug ,warn ,erro四种级别，这里我们注入info级别
        startTime.set(System.currentTimeMillis());

        //获取servlet请求对象---因为这不是控制器，这里不能注入HttpServletRequest，但springMVC本身提供ServletRequestAttributes可以拿到
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();

        HttpServletRequest request = attributes.getRequest();
        //请求的url
        LOGGER.info("=======> URL:" + request.getRequestURL().toString());
        LOGGER.info("=======> METHOD:" + request.getMethod());
        // 请求的是哪个类，哪种方法
        LOGGER.info("=======> CLASS_METHOD:" + joinPoint.getSignature().getDeclaringTypeName() + "."
                + joinPoint.getSignature().getName());
        // 方法本传了哪些参数
        LOGGER.info("=======> PARAMS:" + Arrays.toString(joinPoint.getArgs()));
    }

    //方法的返回值注入给ret ,暂时注释，需要时再放开
    //@AfterReturning(returning = "ret", pointcut = "integrationAopLog()")
    public void doafter (Object ret) {
        // 响应的内容---方法的返回值responseEntity
        LOGGER.info("=======> RESPONSE:" + ret);
        LOGGER.info("=======> SPEND:" + (System.currentTimeMillis() - startTime.get()));
    }

    /**
     * 计算接口执行时间
     */
    @AfterReturning(pointcut = "wmsWebAopLog()")
    public void doAfterReturing () {
        long costTime = System.currentTimeMillis() - startTime.get();
        LOGGER.info("=======> 耗费时间: " + costTime + "ms");
    }

}
